﻿using System;
using System.Globalization;
using System.Reflection;
using System.Text;
using System.Web.Http;
using Microsoft.Owin.Hosting;
using Owin;
using RockBus.Initialization.Interfaces;
using RockBus.Logging.Interfaces;
using RockBus.ServiceModel;
using RockBus.Services.SignalR;
using RockBus.Services.WebApi;

namespace RockBus.Hosting.Owin
{
    public class OwinHostingInitialization : IInitialization
    {
        private const string CbrServiceFullName = "RockBus.Services.CbrService";

        public OwinHostingInitialization(ILogger logger)
        {
            this.Logger = logger;
            this.WebApiConfiguration = new WebApiConfiguration(logger);
            this.SignalRConfiguration = new SignalRConfiguration(logger);
        }

        private ILogger Logger { get; set; }

        private SignalRConfiguration SignalRConfiguration { get; set; }

        private WebApiConfiguration WebApiConfiguration { get; set; }

        private string BaseAddress { get; set; }

        /// <summary>
        /// Called when in Self-Hosted mode.
        /// </summary>
        public void Initialize()
        {
            // Yep, we're referencing WCF's ServiceModel! From my cold bare hands... :)
            var baseAddresses = ConfigurationHelper.GetBaseAddresses(CbrServiceFullName);
            var baseAddressUri = baseAddresses["http"];

            this.BaseAddress = baseAddressUri.ToString().Replace("/CbrService.svc/", "");
            WebApp.Start(this.BaseAddress, this.Configure);
        }

        /// <summary>
        /// Called from Web (IIS) hosted ode from Startup.
        /// </summary>
        /// <param name="appBuilder"></param>
        public void Configure(IAppBuilder appBuilder)
        {
            this.Logger.LogDebug(MethodBase.GetCurrentMethod(), "Configuring WebApi and SignalR.");

            // Configure SignalR
            this.SignalRConfiguration.Configure();
            appBuilder.MapSignalR();

            // Configure Web API for self-host.
            var config = new HttpConfiguration();
            this.WebApiConfiguration.Configure(config);
            appBuilder.UseWebApi(config);

            appBuilder.UseStaticFiles();

            appBuilder.Run(context =>
            {
                context.Response.ContentType = "text/plain";
                return context.Response.WriteAsync("RockBus Default.");
            });

            var sb = new StringBuilder("WebApi listening on the following routes:");
            sb.AppendLine();

            if (!string.IsNullOrEmpty(this.BaseAddress))
            {
                foreach (var route in config.Routes)
                {
                    var absoluteAddress = ConfigurationHelper.GetUri(new Uri(this.BaseAddress, UriKind.Absolute), route.RouteTemplate);
                    sb.AppendLine(absoluteAddress.ToString());
                }
            }
            else
            {
                foreach (var route in config.Routes)
                {
                    sb.AppendLine(route.RouteTemplate);
                }
            }

            this.Logger.LogInfo(MethodBase.GetCurrentMethod(), sb.ToString());
        }
    }
}
